#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "estruturas.h"
#include "loadConfig.h"
#include "loadVocab.h"
#include "loadHMM.h"
#include "loadGrammar.h"
#include "reconheceFrases.h"
#include "arvore.h"

int main()
{
	struct configBusca searchConfig; // search algorithm configurations
	char grammarFile[512]; // file with the language model
	char HMMFile[512]; // file with the HMM parameters
	struct vocab vocabulary; // stores the vocabulary
	struct modelo_HMM HMM; // stores the acoustic models
	struct bigram *grammar=NULL; // stores the bigram information
	long nTerms;	// number of entries in the grammar
    char ch;
    
    int MaxProfundidade; // profundidade maxima observada em todas as arvores lexicas
    int n_arvores; // numero de arvores geradas a partir do arquivo de vocabulario
    int* n_nos; // numero de nos em cada arvore
    struct no ***vocab; // armazena as palavras do vocabulario em arvores
    int ***lista; // estrutura que armazena os nos pertencentes a cada nivel, para cada arvore
    int *profundidades; // indica a profundidade do no mais profundo em cada arvore
  	int **quantos; // indica quantos elementos existem em cada nivel de cada uma das listas
    
	// Loading configurations
	loadConfig("teste.cfg",&searchConfig,grammarFile,HMMFile);

	// Loading Vocabulary
	CarregaVocabulario("vocab.txt",&vocabulary);
	
	// Loading HMMs
	loadHMM(HMMFile,&HMM);
  
	// Loading Grammar
	if (searchConfig.useGrammar == 1)
		loadGrammar(grammarFile,&nTerms,&grammar);

    // Generating and loading lexicon tree
	GeraArvores(&MaxProfundidade,vocabulary);
	CarregaArvores(searchConfig.numberOfLevels,&n_arvores,HMM.n_estados,&n_nos,&vocab);
	
	// Generating and load search lists
	GeraListas(MaxProfundidade,n_arvores,n_nos,vocab[1]);
	CarregaListas(&lista,n_arvores,&profundidades,n_nos,&quantos);
	
	// Recognizing utterances
	puts("Press <ENTER> and say a word.");
	ch=getchar();
	
	while(ch!='0')
	{
    	reconheceFrases(searchConfig,HMM,grammar,nTerms,vocabulary,MaxProfundidade,n_arvores,n_nos,vocab,lista,profundidades,quantos);
    	puts("Press <ENTER> and say a word.");
		ch=getchar();
	}
    // Freeing memory
    DesalocaArvores(searchConfig.numberOfLevels,n_arvores,&n_nos,&vocab);
    DesalocaListas(&lista,n_arvores,&profundidades,&quantos);
	DesalocaVocabulario(&vocabulary);
    freeHMM(&HMM);
	free(grammar);
	
	return (0);
}
